package tp.pr4.items;

import tp.pr4.gui.RobotPanel;

/**
 * A container of items. It can be employed by any class that stores items. 
 * A container cannot store two items with the same identifier
 * It provides methods to add new items, access them and remove them from 
 * the container.
 * @author Alvaro Saez Hernando
 * @author Noel Clemente Montero 
 */
public class ItemContainer {
	
	private static final String LINE_SEPARATOR = System.lineSeparator();
	private Item[] container;
	private int num;
	
	/**
	 * Creates the empty container
	 */
	public ItemContainer(){
		this.container = new Item[100];
		this.num = 0;
	}
	

	/**
	 * Returns the container's size
	 * @return The number of items in the container
	 */
	public int numberOfItems(){
		return this.num;
	}
	
	/**
	 * Add an item to the container. The operation can fail, returning false
	 * @param item - The name of the item to be added.
	 * @return true if and only if the item is added, i.e.,
	 *  an item with the same identifier does not exists in the container
	 */
	public boolean addItem(Item item) {
		boolean added;
		int pos = posItem(item.getId());
		if (pos != -1)
			added = false;
		else{
			pos = whereInsert(item.getId());
			this.moveItemRight(pos);
			this.container[pos]=item;
			added = true;
		}
			return added;
	}
	
	/**
	 * Returns the item from the container according to the item name
	 * @param id - Item name
	 * @return Item with that name or null if the container does not store an item with that name.
	 */
	public Item getItem(String id){
		
		int i = 0;
		while (i < this.num) {
			if (this.container[i].getId().equalsIgnoreCase(id)) {
				return this.container[i];
			}
			i++;
		}return null;
	}
	
	/**
	 * Returns and deletes an item from the inventory. This operation can fail, returning null
	 * @param id - Name of the item
	 * @return An item if and only if the item identified by id exists in the 
	 * inventory. Otherwise it returns null
	 */
	public Item pickItem(String id) {
		Item picked;
		int pos = posItem(id);
		if (pos == -1)
			picked = null;
		else{
			picked = getItem(id);
			remove(pos);
		}
		return picked;
	}
	
	/**
	 * Generates a String with information about the items contained in the container. 
	 * Note that the items must appear sorted but the item name.
	 */
	public String toString(){
		String text = "";
			for (int i = 0; i<num; i++){
				text += LINE_SEPARATOR + "   " + this.container[i].getId();			
			}
			return text;
	}
	
	/**
	 * Checks if the Item with this id exists in the container
	 * @param id - Name of the item.
	 * @return true if the container as an item with that name.
	 */
	public boolean containsItem(String id){
		boolean found = false;
		for(int i=0; i<num ; i++){
			if(container[i].getId().equals(id)){
				found = true;
			}
		}
		return found;
	}
	
	/**
	 * Use an item, removing the item from the inventory if the item can not be used any more
	 * @param item - to be used
	 */
	public void useItem(Item item){
		int pos;
		if(!item.canBeUsed()){
			pos = posItem(item.getId());
			remove(pos);		
		}	
	}
	
	/**
	 * View items of container.
	 * @return items of container
	 */
	public String viewItems() {

		String items = "";
		if (numberOfItems() == 0) {
			return "WALL·E says: My inventory is empty" + LINE_SEPARATOR;
		} else {
			for (int i = 0; i < numberOfItems(); i++) {
				items += LINE_SEPARATOR + "   " + container[i].getId();
			}
			System.out.print("WALL·E says: I am carrying the following items");
			return items;
		}
	}
	
	/**
	 * Sets a panel in order to show the container information in a GUI
	 * @param robotPanel The panel where the container will show its information
	 */
	public void setRobotPanel(RobotPanel robotPanel){
		
	}
	
	//-------------------------METODOS PRIVADOS-----------------------------------------------//
	
	/**
	 * Removes item
	 * @param pos
	 */
	private void remove(int pos){
		this.moveItemLeft(pos);	
	}
	
	/**
	 * Searchs item
	 * @param id
	 * @return posItem
	 */
	private int posItem(String id) {
		int i = 0;
		while (i < this.num) {
			if (this.container[i].getId().equalsIgnoreCase(id)) {
				return i;
			}
			i++;
		}
		return -1;
	}
	
	/**
	 * Searchs position where to insert
	 * @param id
	 * @return position
	 */
	private int whereInsert(String id){
		int i = 0;
		while (i < this.num) {
			if (this.container[i].getId().compareToIgnoreCase(id)>0) {
				return i;
			}else
				i++;
		}
		return i;
	}
	
	/**
	 * Moves all item to right
	 * @param pos
	 */
	private void moveItemRight(int pos) {
		
		for (int j = this.num; j >= pos; j--) {
			this.container[j+1] = this.container[j];
		}
		this.num++;
	}
	
	/**
	 * Moves all item to left
	 * @param pos
	 */
	private void moveItemLeft(int pos) {
		for (int j = pos; j < this.num; j++) {
			this.container[j] = this.container[j + 1];
		}
		this.num--;
	}
	

}
